<template>
  <div ref="rootRef" class="h-full overflow-y-auto bg-white">
    <div class="h-full p-5">
      <!-- 页面标题 -->
      <div class="text-xl font-bold mb-4 pb-2.5 border-b">编制调车计划</div>
      <!-- 页面查询区域 -->
      <div class="relative h-16 mb-4 -mx-5" :class="{ 'overflow-hidden': isShrink }">
        <div
          class="absolute z-10 flex justify-between w-full bg-white"
          :class="{ 'shadow-bottom': !isShrink }"
        >
          <!-- 查询表单 -->
          <div class="flex-1 pl-5">
            <el-form :model="queryForm" inline label-position="top">
              <el-form-item
                v-for="(item, index) in queryFormConfig"
                :key="index"
                class="w-60"
                :label="item.fieldLabel"
              >
                <!-- 普通输入框 -->
                <template v-if="!item.fieldType || item.fieldType === 'INPUT'">
                  <el-input
                    class="w-full -mt-1"
                    v-model.trim="queryForm[item.fieldName]"
                    placeholder="请输入"
                    clearable
                  />
                </template>
                <!-- 普通输入框(数字) -->
                <template v-if="item.fieldType === 'INPUT_NUMBER'">
                  <el-input-number
                    class="!w-full -mt-1"
                    v-model.trim="queryForm[item.fieldName]"
                    :min="0"
                    :precision="0"
                    placeholder="请输入"
                    clearable
                  />
                </template>
                <!-- 普通下拉框 -->
                <template v-if="item.fieldType === 'SELECT'">
                  <el-select
                    class="w-full -mt-1"
                    v-model="queryForm[item.fieldName]"
                    placeholder="请选择"
                    filterable
                    clearable
                  >
                    <el-option
                      v-for="(option, index) in item.fieldOptions"
                      :key="index"
                      :label="option.label"
                      :value="option.value"
                    />
                  </el-select>
                </template>
                <!-- 单个日期选择 -->
                <template v-if="item.fieldType === 'DATE'">
                  <el-date-picker
                    class="-mt-1"
                    v-model="queryForm[item.fieldName]"
                    type="date"
                    :prefix-icon="calendarIcon"
                    placeholder="选择日期"
                    value-format="YYYY-MM-DD"
                  />
                </template>
                <!-- 日期范围选择 -->
                <template v-if="item.fieldType === 'RANGE_DATE'">
                  <el-date-picker
                    class="-mt-1"
                    popper-class="limited-picker"
                    v-model="queryForm[item.fieldName]"
                    :clearable="false"
                    :editable="false"
                    type="daterange"
                    :prefix-icon="calendarIcon"
                    range-separator="~"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    value-format="YYYY-MM-DD"
                    :disabled-date="disabledDate"
                    @calendar-change="onCalendarChange"
                    :default-value="[
                      dayjs().subtract(60, 'day').format('YYYY-MM-DD'),
                      dayjs().format('YYYY-MM-DD')
                    ]"
                  />
                </template>
                <!-- 日期范围选择(无限制) -->
                <template v-if="item.fieldType === 'RANGE_DATE_FREE'">
                  <el-date-picker
                    class="-mt-1"
                    v-model="queryForm[item.fieldName]"
                    type="daterange"
                    :prefix-icon="calendarIcon"
                    range-separator="~"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    value-format="YYYY-MM-DD"
                  />
                </template>
                <!-- 单个日期时间选择 -->
                <template v-if="item.fieldType === 'DATETIME'">
                  <el-date-picker
                    class="-mt-1"
                    v-model="queryForm[item.fieldName]"
                    type="datetime"
                    :prefix-icon="clockIcon"
                    placeholder="选择时间"
                    value-format="YYYY-MM-DD HH:mm"
                    format="YYYY-MM-DD HH:mm"
                  />
                </template>
                <!-- 日期时间范围选择 -->
                <template v-if="item.fieldType === 'RANGE_DATETIME'">
                  <el-date-picker
                    class="-mt-1"
                    popper-class="limited-picker"
                    v-model="queryForm[item.fieldName]"
                    :clearable="false"
                    :editable="false"
                    type="datetimerange"
                    :prefix-icon="clockIcon"
                    range-separator="~"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                    value-format="YYYY-MM-DD HH:mm"
                    format="YYYY-MM-DD HH:mm"
                    :disabled-date="disabledDate"
                    :default-value="[
                      dayjs().subtract(60, 'day').format('YYYY-MM-DD HH:mm'),
                      dayjs().format('YYYY-MM-DD HH:mm')
                    ]"
                    @calendar-change="onCalendarChange"
                    @visible-change="onVisibleChange"
                  />
                </template>
                <!-- 日期时间范围选择(无限制) -->
                <template v-if="item.fieldType === 'RANGE_DATETIME_FREE'">
                  <el-date-picker
                    class="-mt-1"
                    v-model="queryForm[item.fieldName]"
                    type="datetimerange"
                    :prefix-icon="clockIcon"
                    range-separator="~"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                    value-format="YYYY-MM-DD HH:mm"
                    format="YYYY-MM-DD HH:mm"
                  />
                </template>
              </el-form-item>
            </el-form>
          </div>
          <!-- 表单查询功能区 -->
          <div class="pr-5 w-60 pt-[22px] flex justify-between">
            <div class="block">
              <el-button type="primary" @click="onQuery">查询</el-button>
              <el-button @click="onReset">重置</el-button>
            </div>
            <div class="block mt-1 mr-4">
              <el-button link @click="isShrink = !isShrink">
                {{ isShrink ? '展开' : '收起' }}
                <el-icon
                  class="ml-1 duration-300 ease-in-out"
                  :style="{
                    transform: isShrink ? 'rotate(180deg)' : 'rotate(0deg)'
                  }"
                  ><ArrowUp />
                </el-icon>
              </el-button>
            </div>
          </div>
        </div>
      </div>
      <!-- 页面列表区域与右侧制动设备区域 -->
      <div class="flex w-full pb-5 overflow-y-auto">
        <!-- 页面列表区域 -->
        <div ref="tableArea" class="flex-1 min-w-0 bg-white">
          <!-- 表格头部功能区 -->
          <div class="flex justify-between items-center h-[60px] bg-[#fafafa] border">
            <div class="flex">
              <!-- 头部左侧新增按钮 -->
              <el-button type="primary" class="ml-5" @click="openDialog">
                <el-icon size="18" class="mr-1"><Plus /></el-icon>创建调车计划
              </el-button>
              <el-button type="primary" class="ml-5" @click="toggleBrakeSidebar">
                制动设备
              </el-button>
              <div
                class="flex items-center font-semibold border-2 border-[#697dff] box-border py-1.5 pr-4 bg-[#e8edff] rounded ml-2.5 leading-none text-sm"
              >
                <div class="ml-4">
                  <span class="mr-2">总车皮数:</span>
                  <span class="text-[#697dff]">{{ statisticData?.totalWagon ?? '--' }}</span>
                </div>
                <div class="ml-4">
                  <span class="mr-2">重车:</span>
                  <span class="text-[#697dff]">{{ statisticData?.heavyWagon ?? '--' }}</span>
                </div>
                <div class="ml-4">
                  <span class="mr-2">空车:</span>
                  <span class="text-[#697dff]">{{ statisticData?.emptyWagon ?? '--' }}</span>
                </div>
              </div>
            </div>
            <!-- 头部右侧功能按钮 -->
            <div class="flex">
              <el-tooltip
                v-for="(item, index) in tableHeaderConfigs"
                :key="index"
                effect="dark"
                :content="item.label"
                placement="top"
              >
                <template v-if="item.icon === 'FullScreen'">
                  <span
                    v-if="!isFullScreen"
                    class="flex items-center justify-center w-8 h-8 mr-5 border rounded-full cursor-pointer"
                    :class="{ 'border-[#697dff] icon-hover': isHovering === item.icon }"
                    @click="item.click"
                    @mouseover="isHovering = item.icon"
                    @mouseleave="isHovering = ''"
                  >
                    <el-icon size="18" color="#9d9d9d">
                      <!-- 通过动态组件实现对不同icon的渲染 -->
                      <component :is="item.icon"></component>
                    </el-icon>
                  </span>
                  <span
                    v-else
                    class="flex items-center justify-center w-8 h-8 mr-5 border rounded-full cursor-pointer"
                    :class="{ 'border-[#697dff] icon-hover': isHovering === item.icon }"
                    @mouseover="isHovering = item.icon"
                    @mouseleave="isHovering = ''"
                  >
                    <el-icon size="18" color="#9d9d9d" @click="item.click">
                      <!-- 由于Element Plus没有自带缩小图标，如需更改可自行更改 -->
                      <Close />
                    </el-icon>
                  </span>
                </template>
                <span
                  v-else
                  class="flex items-center justify-center w-8 h-8 mr-5 border rounded-full cursor-pointer"
                  :class="{ 'border-[#697dff] icon-hover': isHovering === item.icon }"
                  @mouseover="isHovering = item.icon"
                  @mouseleave="isHovering = ''"
                  @click="item.click"
                >
                  <el-icon size="18" color="#9d9d9d">
                    <!-- 通过动态组件实现对不同icon的渲染 -->
                    <component :is="item.icon"></component>
                  </el-icon>
                </span>
              </el-tooltip>
            </div>
          </div>
          <!-- 表格 -->
          <el-table
            :data="tableData"
            border
            header-row-class-name="h-14"
            header-cell-class-name="text-[#333] header-cell-custom"
            cell-class-name="h-12"
            class="w-full table-custom"
            max-height="calc(100vh - 240px)"
          >
            <template #empty>
              <div class="flex flex-col items-center py-3">
                <img :src="nodata" alt="暂无数据" class="mx-auto" />
                <span class="text-center text-gray-400 leading-6 pr-3">暂无数据</span>
              </div>
            </template>
            <!-- 序号，可根据实际需要增删 -->
            <el-table-column
              type="index"
              class-name="index-column"
              center
              label="序号"
              fixed="left"
              width="60"
            />
            <!-- 表格列配置 -->
            <template v-for="item in tableColumnsConfig" :key="item.fieldName">
              <el-table-column
                :label="item.fieldLabel"
                :prop="item.fieldName"
                :formatter="item.format"
                :fixed="item.fixMode"
                :min-width="item.width ? item.width : 100"
              >
                <template #default="{ row, $index }">
                  <div
                    class="relative flex items-center w-full h-full pl-2.5 cell-custom"
                    @dragover="onDragOverCell"
                    @dragleave="onDragLeaveCell"
                    @drop="dropToCell($event, row, item.fieldName)"
                    @mouseover="mouseOverCell($event, row, item.fieldName)"
                    @mouseleave="mouseLeaveCell($event, row, item.fieldName)"
                  >
                    <div
                      v-if="row[item.fieldName]?.hasLeftIronShoe"
                      class="cursor-move"
                      draggable="true"
                      @dragstart="
                        dragIronShoeFromCellLeft(
                          $event,
                          row[item.fieldName],
                          item.fieldName,
                          $index
                        )
                      "
                    >
                      <div
                        class="absolute left-0 bottom-0 border-x-[18px] border-y-[13px] border-l-[#ff3333] border-b-[#ff3333] border-r-transparent border-t-transparent"
                      ></div>
                      <div class="absolute bottom-0 left-0 pl-px text-xs leading-none text-white">
                        {{ `#${row[item.fieldName]?.leftIronShoeId}` }}
                      </div>
                    </div>
                    <!-- 右铁鞋 -->
                    <div
                      v-if="row[item.fieldName]?.hasRightIronShoe"
                      class="cursor-move"
                      draggable="true"
                      @dragstart="
                        dragIronShoeFromCellRight(
                          $event,
                          row[item.fieldName],
                          item.fieldName,
                          $index
                        )
                      "
                    >
                      <div
                        class="absolute right-0 bottom-0 border-x-[18px] border-y-[13px] border-r-[#ff3333] border-b-[#ff3333] border-l-transparent border-t-transparent"
                      ></div>
                      <div class="absolute bottom-0 right-0 pr-px text-xs leading-none text-white">
                        {{ `#${row[item.fieldName]?.rightIronShoeId}` }}
                      </div>
                    </div>
                    <!-- 手制动机 -->
                    <img
                      v-if="row[item.fieldName]?.hasHandBrake"
                      :src="handBrake"
                      @dragstart="dragHandBrakeFromCell($event, item.fieldName, $index)"
                      class="w-5 h-5 ml-6 cursor-move"
                      alt=""
                    />
                  </div>
                </template>
              </el-table-column>
            </template>
          </el-table>
        </div>
        <!-- 制动设备区域 -->
        <div
          v-if="brakeSidebarVisible"
          class="flex flex-col h-[calc(100vh-180px)] ml-5 border w-60"
        >
          <div class="py-3 pl-4 pr-3 bg-[#edeff3] leading-none">
            <div class="flex items-center justify-between mb-2">
              <div class="font-semibold">制动设备</div>
              <el-icon color="#9c9da0" size="18" class="cursor-pointer" @click="closeBrakeSidebar">
                <Close />
              </el-icon>
            </div>
            <div class="text-[#868686] text-xs">拖动铁鞋或手制动机至相应轨道</div>
          </div>
          <div class="flex-1 overflow-y-auto" @dragover="onDragOver" @drop="dropToSidebar($event)">
            <!-- 铁鞋区域 -->
            <div class="flex items-center py-3 pl-4 pr-3 font-semibold bg-[#fafafa]">
              <div class="w-[3px] h-3 rounded-sm bg-[#697dff]"></div>
              <div class="ml-1.5 text-sm">铁鞋</div>
            </div>
            <div>
              <div
                v-for="item in ironShoeData"
                :key="item.id"
                class="flex items-center justify-between px-4 py-2 hover:bg-[#f0f2ff]"
              >
                <div
                  class="relative cursor-move select-none"
                  draggable="true"
                  @dragstart="dragIronShoe($event, item)"
                  v-if="!item.alreadyUsed"
                >
                  <div
                    class="border-x-[21px] border-y-[17px] border-l-[#ff3333] border-b-[#ff3333] border-r-transparent border-t-transparent"
                  ></div>
                  <div class="absolute bottom-0 left-0 pl-px text-sm text-white select-none">
                    {{ `#${item.id}` }}
                  </div>
                </div>
                <div class="relative cursor-not-allowed" v-else>
                  <div
                    class="border-x-[21px] border-y-[17px] border-l-[#a7a7a7] border-b-[#a7a7a7] border-r-transparent border-t-transparent"
                  ></div>
                  <div class="absolute bottom-0 left-0 pl-px text-sm text-white select-none">
                    {{ `#${item.id}` }}
                  </div>
                </div>
                <div class="text-sm text-[#222] break-words text-right" v-if="item.alreadyUsed">
                  {{ `去向: ${item.destination}` }}
                </div>
              </div>
            </div>
            <!-- 手制动机区域 -->
            <div class="flex items-center py-3 pl-4 pr-3 font-semibold bg-[#fafafa]">
              <div class="w-[3px] h-3 rounded-sm bg-[#697dff]"></div>
              <div class="ml-1.5 text-sm">手制动机</div>
            </div>
            <div>
              <div class="flex items-center justify-between px-4 py-2 hover:bg-[#f0f2ff]">
                <img
                  :src="handBrake"
                  @dragstart="dragHandBrake($event)"
                  class="w-6 h-6 cursor-move select-none"
                  alt=""
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 编制调车计划弹窗 -->
    <createShuntingPlan v-model:visible="dialogVisible" @getData="getData" />
    <!-- tooltip -->
    <div
      ref="tooltipRef"
      v-show="tooltipConfigs.visible"
      class="absolute flex flex-wrap pointer-events-none w-96 break-words z-20 bg-[rgba(0,0,0,0.5)] rounded pl-3 pt-2 text-white text-sm"
      :style="{
        top: `${tooltipConfigs.position.top}px`,
        left: `${tooltipConfigs.position.left}px`
      }"
    >
      <!-- 车皮号 进厂车次 品名 停时 车型 载重 自重 皮重 列检结果 货检结果 货物发站 货物到站 厂外发站 收货单位 备注 -->
      <template v-for="item in tooltipDataConfig" :key="item.name">
        <div v-if="item.name === 'remark'" class="w-full pb-2 break-all">
          <span class="mr-2">{{ `${item.label}:` }}</span>
          <span>{{ tooltipConfigs.content[item.name] }}</span>
        </div>
        <div v-else class="w-1/2 pb-2 pr-3 break-all">
          <span class="mr-2">{{ `${item.label}:` }}</span>
          <span>{{ tooltipConfigs.content[item.name] ?? '--' }}</span>
          <span v-if="item.unit">{{ item?.unit }}</span>
        </div>
      </template>
    </div>
    <!-- 导出弹窗 -->
    <el-dialog
      v-model="exportDialogVisible"
      modal-class="el-dialog-custom"
      title="导出确认"
      width="40%"
      :close-on-click-modal="false"
    >
      <div
        class="flex flex-col mx-2.5 py-2 px-5 h-48 border border-[#81d3f8] bg-[#e6f7ff] rounded-lg"
      >
        <div class="font-bold text-black">查询条件预览</div>
        <div class="flex flex-wrap content-start flex-1 my-3 overflow-y-auto export-dialog-custom">
          <div class="w-1/2 mb-1" v-for="item in queryContentWithoutTime" :key="item.label">
            <div class="flex">
              <div class="w-20 text-right">{{ `${item.label}:` }}</div>
              <div class="flex-1 min-w-0 px-2 break-all">{{ item.value }}</div>
            </div>
          </div>
        </div>
        <div class="cursor-pointer text-[#027db4]" @click="clearQueryWithoutTime">清空查询条件</div>
      </div>
      <div class="export-dialog-custom mt-4 mx-2.5 px-2 h-48 overflow-y-auto">
        <div
          v-for="item in queryContentTime"
          :key="item.label"
          class="flex items-center justify-between h-12"
        >
          <div class="flex items-center">
            <div>{{ `${item.label}:` }}</div>
            <template v-if="item.type === 'RANGE_DATETIME'">
              <el-date-picker
                class="!w-[330px] ml-2"
                popper-class="limited-picker"
                v-model="queryFormForExport[item.name]"
                :clearable="false"
                :editable="false"
                type="datetimerange"
                range-separator="~"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                value-format="YYYY-MM-DD HH:mm"
                format="YYYY-MM-DD HH:mm"
                :disabled-date="disabledDateForExport"
                @calendar-change="onCalendarChange"
                @visible-change="onVisibleChange"
              />
            </template>
            <template v-if="item.type === 'RANGE_DATE'">
              <el-date-picker
                class="!w-[330px] ml-2"
                popper-class="limited-picker"
                v-model="queryFormForExport[item.name]"
                :clearable="false"
                :editable="false"
                type="daterange"
                range-separator="~"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="YYYY-MM-DD"
                :disabled-date="disabledDateForExport"
                @calendar-change="onCalendarChange"
              />
            </template>
          </div>
          <div
            v-if="queryContentTime.length > 1"
            class="text-[#d9001b] cursor-pointer select-none"
            @click="deleteTimeItem(item.name)"
          >
            删除
          </div>
        </div>
      </div>
      <template #footer>
        <el-button @click="exportDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="onExport">确 定</el-button>
      </template>
    </el-dialog>
    <!-- 导出-数据处理中弹窗 -->
    <el-dialog
      modal-class="el-dialog-export-confirm-custom"
      v-model="exportConfirmedDialogVisible"
      width="36%"
      :close-on-click-modal="false"
      @closed="clearTimer"
    >
      <div class="flex flex-col items-center">
        <div class="flex items-center mt-8">
          <el-icon size="50" color="#52c41a"><SuccessFilled /></el-icon>
          <div class="ml-3 text-3xl font-bold">数据处理中</div>
        </div>
        <div class="text-base mt-14">
          点击跳转<span class="text-[#02a7f0] font-bold cursor-pointer" @click="moveToExportPage"
            >历史导出记录</span
          >页面，可下载导出数据
        </div>
        <div class="mb-8 text-base text-gray-400 mt-14">{{ remainingSeconds }}秒后自动关闭弹窗</div>
      </div>
    </el-dialog>
    <!-- 右侧抽屉弹窗 -->
    <el-drawer
      ref="rightDrawer"
      v-model="drawerVisible"
      title="管理展示字段"
      direction="rtl"
      size="30%"
      @closed="handleDrawerClose"
      destroy-on-close
    >
      <el-radio-group v-model="drawerAreaType">
        <el-radio-button label="查询区" />
        <el-radio-button label="列表区" />
      </el-radio-group>
      <div class="py-5 text-sm">
        选中的字段将会在{{ drawerAreaType }}中显示，默认显示所有{{
          drawerAreaType.slice(0, -1)
        }}字段。 点击上移、下移，或直接拖动字段名称可调整字段展示顺序。
      </div>
      <div v-show="drawerAreaType === '查询区'">
        <div class="bg-[#e9ebf0]">
          <div class="flex justify-between p-2.5 border-b border-x">
            <div class="flex items-center">
              <el-checkbox
                v-if="queryFormConfigDrawer.length"
                v-model="queryCheckAll"
                :indeterminate="isIndeterminateQuery"
                @change="handleCheckAllChangeQuery"
              />
              <el-checkbox v-else :model-value="true" disabled />
              <span class="text-sm ml-7">字段名称</span>
            </div>
            <div class="flex items-center">
              <div class="w-[72px] text-sm">操作</div>
            </div>
          </div>
        </div>
        <div>
          <div
            class="even:bg-[#fafafa]"
            v-for="item in queryFormConfigDrawerFixedLeft"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b border-x">
              <div class="flex items-center">
                <el-checkbox :model-value="true" disabled />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
            </div>
          </div>
        </div>
        <div ref="sortableDrawerQuery">
          <div
            :class="
              queryFormConfigDrawerFixedLeft.length % 2 === 0
                ? 'even:bg-[#fafafa]'
                : 'odd:bg-[#fafafa]'
            "
            v-for="(item, index) in queryFormConfigDrawer"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b border-x">
              <div class="flex items-center">
                <el-checkbox
                  v-model="queryFormConfigFilterDrawer[item.fieldName]"
                  @change="handleCheckedFieldChange"
                />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
              <div class="flex items-center justify-between">
                <div
                  class="mr-4 text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed': index === 0,
                    'cursor-pointer': index !== 0
                  }"
                  @click="changeOrderQuery(index, 'up')"
                >
                  上移
                </div>
                <div
                  class="text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed': index === queryFormConfigDrawer.length - 1,
                    'cursor-pointer': index !== queryFormConfigDrawer.length - 1
                  }"
                  @click="changeOrderQuery(index, 'down')"
                >
                  下移
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div
            :class="
              (queryFormConfigDrawerFixedLeft.length + queryFormConfigDrawer.length) % 2 === 0
                ? 'even:bg-[#fafafa]'
                : 'odd:bg-[#fafafa]'
            "
            v-for="item in queryFormConfigDrawerFixedRight"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b border-x">
              <div class="flex items-center">
                <el-checkbox :model-value="true" disabled />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-show="drawerAreaType === '列表区'">
        <div class="bg-[#e9ebf0]">
          <div class="flex justify-between p-2.5 border-b border-x">
            <div class="flex items-center">
              <el-checkbox
                v-if="tableColumnsConfigDrawer.length"
                v-model="tableCheckAll"
                :indeterminate="isIndeterminateTable"
                @change="handleCheckAllChangeTable"
              />
              <el-checkbox v-else :model-value="true" disabled />
              <span class="text-sm ml-7">字段名称</span>
            </div>
            <div class="flex items-center">
              <div class="w-[72px] text-sm">操作</div>
            </div>
          </div>
        </div>
        <div>
          <div
            class="even:bg-[#fafafa]"
            v-for="item in tableColumnsConfigDrawerFixedLeft"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b border-x">
              <div class="flex items-center">
                <el-checkbox :model-value="true" disabled />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
            </div>
          </div>
        </div>
        <div ref="sortableDrawerTable">
          <div
            :class="
              tableColumnsConfigDrawerFixedLeft.length % 2 === 0
                ? 'even:bg-[#fafafa]'
                : 'odd:bg-[#fafafa]'
            "
            v-for="(item, index) in tableColumnsConfigDrawer"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b border-x">
              <div class="flex items-center">
                <el-checkbox
                  v-model="tableColumnsConfigFilterDrawer[item.fieldName]"
                  @change="handleCheckedFieldChangeTable"
                />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
              <div class="flex items-center justify-between">
                <div
                  class="mr-4 text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed': index === 0,
                    'cursor-pointer': index !== 0
                  }"
                  @click="changeOrderTable(index, 'up')"
                >
                  上移
                </div>
                <div
                  class="text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed':
                      index === tableColumnsConfigDrawer.length - 1,
                    'cursor-pointer': index !== tableColumnsConfigDrawer.length - 1
                  }"
                  @click="changeOrderTable(index, 'down')"
                >
                  下移
                </div>
              </div>
            </div>
          </div>
        </div>
        <div>
          <div
            :class="
              (tableColumnsConfigDrawerFixedLeft.length + tableColumnsConfigDrawer.length) % 2 === 0
                ? 'even:bg-[#fafafa]'
                : 'odd:bg-[#fafafa]'
            "
            v-for="item in tableColumnsConfigDrawerFixedRight"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b border-x">
              <div class="flex items-center">
                <el-checkbox :model-value="true" disabled />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="flex items-center justify-center p-5">
        <el-button @click="handleDrawerClose">取消</el-button>
        <el-button type="primary" @click="saveDrawerData">确定</el-button>
      </div>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, watch, nextTick, onBeforeUnmount } from 'vue';
import type { ElDrawer } from 'element-plus';
import dayjs from 'dayjs';
import _ from 'lodash-es';
import { useRouter } from 'vue-router';
import Sortable from 'sortablejs';
import type { SortableEvent } from 'sortablejs';
import localForage from 'localforage';
import calendarIcon from '@/components/CalendarIcon.vue';
import clockIcon from '@/components/ClockIcon.vue';
import handBrake from '@/assets/images/hand-brake.png';
import createShuntingPlan from './createShuntingPlan.vue';
import { ArrowUp, Close, Plus, SuccessFilled } from '@element-plus/icons-vue';
import nodata from '@/assets/images/nodata.png';

onBeforeUnmount(() => {
  clearTimer();
});

/************************************************/
/**************** 参数配置区 开始 ****************/
/************************************************/

interface QueryFormConfigItem {
  /** 字段标签名 */
  fieldLabel: string;
  /** 字段名称 */
  fieldName: string;
  /**
   * 字段类型。
   *
   * - INPUT: 输入框 (默认)
   * - SELECT: 下拉框
   * - DATE: 日期选择器
   * - RANGE_DATE: 日期范围选择器
   * - RANGE_DATE_FREE: 日期范围选择器(无限制)
   * - DATETIME: 日期时间选择器
   * - RANGE_DATETIME: 日期时间范围选择器
   * - RANGE_DATETIME_FREE: 日期时间范围选择器(无限制)
   */
  fieldType?: string;
  /**
   * 字段值类型。
   *
   * - STRING: 字符串 (默认)
   * - NUMBER: 数字
   * - DATE: 日期
   * - ARRAY: 数组
   */
  valueType?: string;
  /**
   * 字段固定模式。
   *
   * - movable: 可拖动 (默认)
   * - left: 固定在左侧
   * - right: 固定在右侧
   */
  fixMode?: 'movable' | 'left' | 'right';
  /** 字段选项，当fieldType为SELECT时，需要传入该字段 */
  fieldOptions?: fieldOptionsItem[];
  /** 其他任意属性 */
  [key: string]: unknown;
}
interface fieldOptionsItem {
  label: string;
  value: string | number;
}
// 查询表单配置项
const queryFormConfigInit: QueryFormConfigItem[] = [
  // 机车 车型 进厂车次 原料名称 车号 股道 占压信号 停时范围
  { fieldLabel: '机车', fieldName: 'locomotive', fieldType: 'SELECT', fieldOptions: [] },
  { fieldLabel: '车型', fieldName: 'carType', fieldType: 'SELECT', fieldOptions: [] },
  { fieldLabel: '进厂车次', fieldName: 'inFactoryTrain' },
  { fieldLabel: '原料名称', fieldName: 'materialName', fieldType: 'SELECT', fieldOptions: [] },
  { fieldLabel: '车号', fieldName: 'carNumber' },
  { fieldLabel: '股道', fieldName: 'track', fieldType: 'SELECT', fieldOptions: [] },
  { fieldLabel: '占压信号', fieldName: 'pressureSignal', fieldType: 'SELECT', fieldOptions: [] },
  { fieldLabel: '最少停时范围（小时）', fieldName: 'minStopTime', fieldType: 'INPUT_NUMBER' },
  { fieldLabel: '最多停时范围（小时）', fieldName: 'maxStopTime', fieldType: 'INPUT_NUMBER' }
];

interface TableColumnsConfigItem {
  /** 表格列名 */
  fieldLabel: string;
  /** 字段名称 */
  fieldName: string;
  /** 列宽度 */
  width?: number;
  /**
   * 字段格式化函数
   * @param row 当前行数据
   * @param column 当前列数据
   * @param cellValue 当前单元格数据
   * @param index 当前行索引
   */
  format?: Function;
  /**
   * 字段固定模式。
   *
   * - movable: 可拖动 (默认)
   * - left: 固定在左侧
   * - right: 固定在右侧
   */
  fixMode?: 'movable' | 'left' | 'right';
  [key: string]: unknown;
}
// 表格显示字段配置项
const tableColumnsConfigInit: TableColumnsConfigItem[] = [
  // 股道1 股道2 股道3 股道4 股道5 股道6 股道7 股道8 股道9 股道10 股道11 股道12 股道13 股道14
  // 电1 电2 钢货位线 牵出线（厂西） 安全线（厂内编组） 安全线（翻车机）机转线
  { fieldLabel: '股道1', fieldName: 'track1', width: 400 },
  { fieldLabel: '股道2', fieldName: 'track2', width: 400 },
  { fieldLabel: '股道3', fieldName: 'track3', width: 400 },
  { fieldLabel: '股道4', fieldName: 'track4', width: 400 },
  { fieldLabel: '股道5', fieldName: 'track5', width: 400 },
  { fieldLabel: '股道6', fieldName: 'track6', width: 400 },
  { fieldLabel: '股道7', fieldName: 'track7', width: 400 },
  { fieldLabel: '股道8', fieldName: 'track8', width: 400 },
  { fieldLabel: '股道9', fieldName: 'track9', width: 400 },
  { fieldLabel: '股道10', fieldName: 'track10', width: 400 },
  { fieldLabel: '股道11', fieldName: 'track11', width: 400 },
  { fieldLabel: '股道12', fieldName: 'track12', width: 400 },
  { fieldLabel: '股道13', fieldName: 'track13', width: 400 },
  { fieldLabel: '股道14', fieldName: 'track14', width: 400 },
  { fieldLabel: '电1', fieldName: 'electric1', width: 400 },
  { fieldLabel: '电2', fieldName: 'electric2', width: 400 },
  { fieldLabel: '钢货位线', fieldName: 'steelGoodsLine', width: 400 },
  { fieldLabel: '牵出线（厂西）', fieldName: 'drawLineWest', width: 400 },
  { fieldLabel: '安全线（厂内编组）', fieldName: 'safetyLineInFactory', width: 400 },
  { fieldLabel: '安全线（翻车机）', fieldName: 'safetyLineOverturn', width: 400 },
  { fieldLabel: '机转线', fieldName: 'machineTurnLine', width: 400 }
];
/************************************************/
/**************** 参数配置区 结束 ****************/
/************************************************/

/**************************************************/
/**************** 参数初始化区 开始 ****************/
/**************************************************/

// 辅助函数: 用于设置下拉框列表中的数据项fieldOptions
const setFieldOptions = (fieldName: string, options: fieldOptionsItem[]) => {
  const field = queryFormConfigInit.find((item) => item.fieldName === fieldName);
  if (field && field.fieldType === 'SELECT') {
    field.fieldOptions = options;
  }
};

// 示例代码: 设置某个下拉框列表中的数据项fieldOptions，正式使用时请删除
const carTypeOptions = [
  { label: '小型车', value: '1' },
  { label: '中型车', value: '2' },
  { label: '大型车', value: '3' }
];
setFieldOptions('carType', carTypeOptions);

// 从查询区配置项queryFormConfig中获取查询表单的初始值
const queryForm = reactive<Record<string, unknown>>({});
// 辅助函数: 用于获取查询表单的初始值
const getDefaultValue = (item: QueryFormConfigItem) => {
  if (!item.valueType && !item.fieldType) {
    return '';
  }
  const formatMap = {
    RANGE_DATE: 'YYYY-MM-DD',
    RANGE_DATETIME: 'YYYY-MM-DD HH:mm'
  };
  switch (item.valueType) {
    case 'ARRAY':
      return [];
    case 'NUMBER':
    case 'DATE':
      return null;
    case 'STRING':
      return '';
    default:
      if (item.fieldType && item.fieldType in formatMap) {
        return [
          dayjs()
            .subtract(60, 'day')
            .format(formatMap[item.fieldType as keyof typeof formatMap]),
          dayjs().format(formatMap[item.fieldType as keyof typeof formatMap])
        ];
      }
      return null;
  }
};
// 重置查询表单
const getQueryForm = () => {
  queryFormConfigInit.forEach((item) => {
    console.log(item, getDefaultValue(item));
    queryForm[item.fieldName] = getDefaultValue(item);
  });
  return queryForm;
};
getQueryForm();

/**************************************************/
/**************** 参数初始化区 结束 ****************/
/**************************************************/

/***************************************************/
/**************** 时间选择器定义 开始 ****************/
/***************************************************/

const firstSelectedDateRef = ref<Date | null>(null);
// 用于记录首个日期时间范围选择器的值，从而限制第二个日期时间范围选择器的可选范围
const onCalendarChange = (dateRange: Date[]) => {
  const [minDate, maxDate] = dateRange;
  if (minDate && !maxDate) {
    firstSelectedDateRef.value = minDate;
  } else {
    firstSelectedDateRef.value = null;
  }
  // 保证在改选日期之后仍然保持年月日输入框禁用
  nextTick(() => {
    const timePickerInnerInputs = document.querySelectorAll(
      '.limited-picker .el-date-range-picker__time-picker-wrap:nth-child(1) input'
    );
    for (const el of timePickerInnerInputs) {
      (el as HTMLInputElement).disabled = true;
    }
  });
};
const createDisabledDate = (durationDays: number = 60, containsToday: boolean = true) => {
  return function (time: Date) {
    const now = dayjs();
    let isFutureDate = dayjs(time).isAfter(now);
    if (!containsToday) {
      isFutureDate = dayjs(time).isAfter(now.subtract(1, 'day'));
    }
    const firstSelectedDay = firstSelectedDateRef.value;
    if (!firstSelectedDay) {
      return isFutureDate;
    } else {
      const selectedDay = dayjs(firstSelectedDay);
      const isOutOfDuration =
        dayjs(time).isBefore(selectedDay.subtract(durationDays, 'day')) ||
        dayjs(time).isAfter(selectedDay.add(durationDays, 'day'));
      return isFutureDate || isOutOfDuration;
    }
  };
};
// 日期时间范围选择器的不可选日期
const disabledDate = createDisabledDate();
// 导出框内的时间范围选择器的不可选日期
const disabledDateForExport = createDisabledDate(365);
// 设置日期时间选择器下拉框中，上方的日期输入框不可选，从而防止用户手动输入日期，导致选择的日期范围不符合要求
const onVisibleChange = (val: boolean) => {
  if (val) {
    firstSelectedDateRef.value = null;
    const timePickerInnerInputs = document.querySelectorAll(
      '.limited-picker .el-date-range-picker__time-picker-wrap:nth-child(1) input'
    );
    for (const el of timePickerInnerInputs) {
      (el as HTMLInputElement).disabled = true;
    }
  }
};

/***************************************************/
/**************** 时间选择器定义 结束 ****************/
/***************************************************/

// 该页面的本地存储的key值，用于存储页面的配置项
const localForageKey = location.pathname;
// 页面的配置项类型
type PageConfig = Record<
  'queryFormOrder' | 'queryFormFilter' | 'tableColumnsOrder' | 'tableColumnsFilter',
  Record<string, number>
>;

// 检查indexedDB中的页面配置项是否正确，如果不正确，则将其清空
const verifyPageConfig = async () => {
  const res: PageConfig | null = await localForage.getItem(localForageKey);
  const queryFormOrder = res?.queryFormOrder;
  const tableColumnsOrder = res?.tableColumnsOrder;

  // 获取之前缓存配置项的键值，即需要参与配置的字段名集合
  const computedQueryOrder = queryFormOrder ? Object.keys(queryFormOrder) : [];
  const computedTableColumnOrder = tableColumnsOrder ? Object.keys(tableColumnsOrder) : [];

  // 计算目前的配置项顺序
  const nowQueryOrder = queryFormConfigInit
    .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
    .map((item) => item.fieldName);
  const nowTableColumnOrder = tableColumnsConfigInit
    .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
    .map((item) => item.fieldName);

  // 如果indexedDB中的配置项和目前的配置项不一致，则将indexedDB中的配置项清空
  if (
    _.difference(computedQueryOrder, nowQueryOrder).length ||
    _.difference(computedTableColumnOrder, nowTableColumnOrder).length ||
    _.difference(nowQueryOrder, computedQueryOrder).length ||
    _.difference(nowTableColumnOrder, computedTableColumnOrder).length
  ) {
    await localForage.removeItem(localForageKey);
  }
};

// 路由实例
const router = useRouter();

const reloadPage = () => {
  getFieldOrderAndFilter();
  onReset();
};

// 查询区和列表区的抽屉区域模板引用
const sortableDrawerQuery = ref<HTMLElement | null>();
const sortableDrawerTable = ref<HTMLElement | null>();

// 查询区配置项的显示顺序
let queryFormConfigOrder: Record<string, number> = {};
// 查询区配置项是否显示
let queryFormConfigFilter: Record<string, number> = {};
// 查询区配置项，用于最终对查询区进行渲染
const queryFormConfig = ref<QueryFormConfigItem[]>([]);
// 查询区配置项的抽屉配置项
const queryFormConfigDrawer = ref<Pick<QueryFormConfigItem, 'fieldName' | 'fieldLabel'>[]>([]);
// 查询区配置项的抽屉配置项: 固定在左侧
const queryFormConfigDrawerFixedLeft = ref<Pick<QueryFormConfigItem, 'fieldName' | 'fieldLabel'>[]>(
  []
);
// 查询区配置项的抽屉配置项: 固定在右侧
const queryFormConfigDrawerFixedRight = ref<
  Pick<QueryFormConfigItem, 'fieldName' | 'fieldLabel'>[]
>([]);
const queryFormConfigFilterDrawer = ref<Record<string, boolean>>({});

// 列表区配置项的显示顺序
let tableColumnsConfigOrder: Record<string, number> = {};
// 列表区配置项是否显示
let tableColumnsConfigFilter: Record<string, number> = {};
// 列表区配置项，用于最终对列表区进行渲染
const tableColumnsConfig = ref<TableColumnsConfigItem[]>([]);
// 列表区配置项的抽屉配置项
const tableColumnsConfigDrawer = ref<Pick<TableColumnsConfigItem, 'fieldName' | 'fieldLabel'>[]>(
  []
);
// 列表区配置项的抽屉配置项: 固定在左侧
const tableColumnsConfigDrawerFixedLeft = ref<
  Pick<TableColumnsConfigItem, 'fieldName' | 'fieldLabel'>[]
>([]);
// 列表区配置项的抽屉配置项: 固定在右侧
const tableColumnsConfigDrawerFixedRight = ref<
  Pick<TableColumnsConfigItem, 'fieldName' | 'fieldLabel'>[]
>([]);
const tableColumnsConfigFilterDrawer = ref<Record<string, boolean>>({});

// 计算查询区和列表区实际渲染的配置项: 辅助计算函数
const computeConfig = (
  initConfig: QueryFormConfigItem[] | TableColumnsConfigItem[],
  orderConfig: Record<string, number>,
  filterConfig: Record<string, number>
) => {
  const fixedLeft = initConfig.filter((item) => item.fixMode === 'left');
  const fixedRight = initConfig.filter((item) => item.fixMode === 'right');
  const movable = initConfig
    .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
    .sort((a, b) => orderConfig[a.fieldName] - orderConfig[b.fieldName])
    .filter((item) => filterConfig[item.fieldName] === 1);

  return [...fixedLeft, ...movable, ...fixedRight];
};
// 计算查询区和列表区实际渲染的配置项: 主函数
const computeFieldConfig = () => {
  queryFormConfig.value = computeConfig(
    queryFormConfigInit,
    queryFormConfigOrder,
    queryFormConfigFilter
  );
  tableColumnsConfig.value = computeConfig(
    tableColumnsConfigInit,
    tableColumnsConfigOrder,
    tableColumnsConfigFilter
  );
};
// 从indexedDB中获取查询区和列表区配置项的显示顺序和是否显示
const getFieldOrderAndFilter = async () => {
  // 检查indexedDB中的页面配置项是否正确，如果不正确，则将其清空
  await verifyPageConfig();
  const res: PageConfig | null = await localForage.getItem(localForageKey);
  let shouldSetItem: boolean = false;
  const CurdStandardPage = (res || {}) as PageConfig;

  if (res && 'queryFormOrder' in res) {
    queryFormConfigOrder = res.queryFormOrder;
  } else {
    queryFormConfigInit
      .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
      .forEach((item, index) => {
        queryFormConfigOrder[item.fieldName] = index;
      });
    // 存入CurdStandardPage中的queryFormOrder配置项里
    CurdStandardPage.queryFormOrder = queryFormConfigOrder;
    shouldSetItem = true;
  }
  if (res && 'queryFormFilter' in res) {
    queryFormConfigFilter = res.queryFormFilter;
  } else {
    queryFormConfigInit
      .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
      .forEach((item) => {
        queryFormConfigFilter[item.fieldName] = 1;
      });
    // 存入CurdStandardPage中的queryFormFilter配置项里
    CurdStandardPage.queryFormFilter = queryFormConfigFilter;
    shouldSetItem = true;
  }
  if (res && 'tableColumnsOrder' in res) {
    tableColumnsConfigOrder = res.tableColumnsOrder;
  } else {
    tableColumnsConfigInit
      .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
      .forEach((item, index) => {
        tableColumnsConfigOrder[item.fieldName] = index;
      });
    // 存入CurdStandardPage中的tableColumnsOrder配置项里
    CurdStandardPage.tableColumnsOrder = tableColumnsConfigOrder;
    shouldSetItem = true;
  }
  if (res && 'tableColumnsFilter' in res) {
    tableColumnsConfigFilter = res.tableColumnsFilter;
  } else {
    tableColumnsConfigInit
      .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
      .forEach((item) => {
        tableColumnsConfigFilter[item.fieldName] = 1;
      });
    // 存入CurdStandardPage中的tableColumnsFilter配置项里
    CurdStandardPage.tableColumnsFilter = tableColumnsConfigFilter;
    shouldSetItem = true;
  }
  if (shouldSetItem) {
    await localForage.setItem(localForageKey, CurdStandardPage);
  }
  computeFieldConfig();
};
getFieldOrderAndFilter();

const isShrink = ref<boolean>(true);
// 表格数据-模拟
const tableData = ref<Record<string, unknown>[]>([]);

const onQuery = async () => {
  isShrink.value = true;
  // TODO: 查询操作
  console.log(queryForm);
  tableData.value = [
    {
      track1: {
        // 车皮号 进厂车次 品名 停时 车型 载重 自重 皮重 列检结果 货检结果 货物发站 货物到站 厂外发站 收货单位 备注
        carNumber: '1638981',
        inFactoryTrain: '202010190832',
        materialName: '焦炭',
        stopTime: '3.89',
        carType: 'N50',
        load: '50',
        selfWeight: '10',
        tare: '5',
        columnCheckResult: '正常',
        goodsCheckResult: '正常',
        goodsSendStation: '重庆市渝北区',
        goodsArriveStation: '日照钢铁厂',
        outFactorySendStation: '重庆市渝北区',
        receivingCompany: '日照钢铁厂',
        remark: '这是一条备注，用于描述这个车辆的情况，这个车辆的情况非常好，它的运输情况也非常好'
      }
    },
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    {}
  ];
  /**
   * 这里需要给tableData和tablePaginationConfig赋值，参考代码：
   * const res = await API.getDataList(); // 获取后端接口数据
   * tableData.value = res.data.list; // 将数据赋值给表格
   * tablePaginationConfig.total = res.data.total; // 将总条数赋值给分页配置项
   */
};
onQuery();

const onReset = () => {
  getQueryForm();
  onQuery();
};

const dialogVisible = ref<boolean>(false);
const openDialog = (row: Record<string, unknown> | null = null) => {
  dialogVisible.value = true;
  // TODO: 新增和编辑逻辑
  row ? console.log(row) : '';
};

const brakeSidebarVisible = ref<boolean>(false);
const toggleBrakeSidebar = () => {
  brakeSidebarVisible.value = !brakeSidebarVisible.value;
};
const closeBrakeSidebar = () => {
  brakeSidebarVisible.value = false;
};
const ironShoeData = ref([
  { id: 1, alreadyUsed: 0, destination: '' },
  { id: 2, alreadyUsed: 0, destination: '' },
  { id: 3, alreadyUsed: 0, destination: '' },
  { id: 4, alreadyUsed: 0, destination: '' },
  { id: 5, alreadyUsed: 0, destination: '' },
  { id: 6, alreadyUsed: 0, destination: '' },
  { id: 7, alreadyUsed: 0, destination: '' },
  { id: 8, alreadyUsed: 0, destination: '' },
  { id: 9, alreadyUsed: 0, destination: '' },
  { id: 10, alreadyUsed: 0, destination: '' }
]);

// 拖拽的图标类型
const dragIconType = ref<'ironShoe' | 'handBrake'>('ironShoe');
const dragIronShoe = (event: DragEvent, item: Record<string, any>) => {
  dragIconType.value = 'ironShoe';
  event.dataTransfer?.setData('ironShoe', item.id);
};
const dragHandBrake = (event: DragEvent) => {
  dragIconType.value = 'handBrake';
  event.dataTransfer?.setData('handBrake', 'handBrake');
};
const dragHandBrakeFromCell = (event: DragEvent, fieldName: string, $index: number) => {
  dragIconType.value = 'handBrake';
  event.dataTransfer?.setData('handBrake', 'handBrakeFromCell');
  event.dataTransfer?.setData('fieldName', fieldName);
  event.dataTransfer?.setData('$index', $index.toString());
};
const dragIronShoeFromCellLeft = (
  event: DragEvent,
  item: Record<string, any>,
  fieldName: string,
  $index: number
) => {
  dragIconType.value = 'ironShoe';
  event.dataTransfer?.setData('ironShoe', item.leftIronShoeId);
  event.dataTransfer?.setData('fieldName', fieldName);
  event.dataTransfer?.setData('$index', $index.toString());
  event.dataTransfer?.setData('position', 'left');
};
const dragIronShoeFromCellRight = (
  event: DragEvent,
  item: Record<string, any>,
  fieldName: string,
  $index: number
) => {
  dragIconType.value = 'ironShoe';
  event.dataTransfer?.setData('ironShoe', item.rightIronShoeId);
  event.dataTransfer?.setData('fieldName', fieldName);
  event.dataTransfer?.setData('$index', $index.toString());
  event.dataTransfer?.setData('position', 'right');
};
const onDragOver = (event: DragEvent) => {
  event.preventDefault();
};
const onDragOverCell = (event: DragEvent) => {
  event.preventDefault();
  event.dataTransfer!.dropEffect = 'move';
  const target = event.target as HTMLElement;
  // 如果拖拽的是手制动机，则整个单元格都显示颜色
  if (dragIconType.value === 'handBrake') {
    target.style.background = 'linear-gradient(to right, #dcfce7 0%, #dcfce7 100%)';
    return;
  }
  // 比较鼠标位置距离左侧和右侧的距离，判断鼠标位置是在单元格左侧还是右侧
  const mouseX = event.clientX;
  const targetLeft = target.getBoundingClientRect().left;
  const targetRight = target.getBoundingClientRect().right;
  const type = mouseX < targetLeft + (targetRight - targetLeft) / 2 ? 'left' : 'right';
  type === 'left'
    ? (target.style.background =
        'linear-gradient(to right, #dcfce7 0%, #dcfce7 50%, transparent 50%, transparent 100%)')
    : (target.style.background =
        'linear-gradient(to right, transparent 0%, transparent 50%, #dcfce7 50%, #dcfce7 100%)');
};
const onDragLeaveCell = (event: DragEvent) => {
  event.preventDefault();
  const target = event.target as HTMLElement;
  target.style.background = '';
};
const dropToCell = (event: DragEvent, row: Record<string, any>, fieldName: string) => {
  event.preventDefault();
  // 恢复背景颜色
  const target = event.target as HTMLElement;
  target.style.background = '';
  const handBrake = event.dataTransfer?.getData('handBrake');
  const previousFieldName = event.dataTransfer?.getData('fieldName');
  const previousIndex = event.dataTransfer?.getData('$index');
  const ironShoeId = event.dataTransfer?.getData('ironShoe');

  // 比较鼠标位置距离左侧和右侧的距离，判断鼠标位置是在单元格左侧还是右侧
  const mouseX = event.clientX;
  const targetLeft = target.getBoundingClientRect().left;
  const targetRight = target.getBoundingClientRect().right;
  const type = mouseX < targetLeft + (targetRight - targetLeft) / 2 ? 'left' : 'right';

  if (
    type === 'left' &&
    row[fieldName] &&
    row[fieldName].hasLeftIronShoe &&
    handBrake !== 'handBrake'
  ) {
    return;
  }
  if (
    type === 'right' &&
    row[fieldName] &&
    row[fieldName].hasRightIronShoe &&
    handBrake !== 'handBrake'
  ) {
    return;
  }

  if (previousFieldName && previousIndex && handBrake !== 'handBrakeFromCell') {
    const previousRow = tableData.value[Number(previousIndex)] as Record<string, any>;
    previousRow[previousFieldName] = previousRow[previousFieldName] || {};
    previousRow[previousFieldName].destination = '';
    if (previousRow[previousFieldName].leftIronShoeId === ironShoeId) {
      previousRow[previousFieldName].hasLeftIronShoe = false;
      previousRow[previousFieldName].leftIronShoeId = null;
    }
    if (previousRow[previousFieldName].rightIronShoeId === ironShoeId) {
      previousRow[previousFieldName].hasRightIronShoe = false;
      previousRow[previousFieldName].rightIronShoeId = null;
    }
  }

  if (handBrake === 'handBrake') {
    row[fieldName] = row[fieldName] || {};
    row[fieldName].hasHandBrake = true;
    return;
  }
  if (handBrake === 'handBrakeFromCell') {
    return;
  }
  const id = event.dataTransfer?.getData('ironShoe');
  row[fieldName] = row[fieldName] || {};
  if (type === 'left') {
    row[fieldName].hasLeftIronShoe = true;
    row[fieldName].leftIronShoeId = id;
  } else {
    row[fieldName].hasRightIronShoe = true;
    row[fieldName].rightIronShoeId = id;
  }
  ironShoeData.value.find((item) => item.id === Number(id))!.alreadyUsed = 1;
  ironShoeData.value.find((item) => item.id === Number(id))!.destination =
    tableColumnsConfigInit.find((item) => item.fieldName === fieldName)!.fieldLabel;
};
const dropToSidebar = (event: DragEvent) => {
  event.preventDefault();
  const previousFieldName = event.dataTransfer?.getData('fieldName');
  const previousIndex = event.dataTransfer?.getData('$index');
  const handBrake = event.dataTransfer?.getData('handBrake');
  const position = event.dataTransfer?.getData('position');
  const previousRow = tableData.value[Number(previousIndex)] as Record<string, any>;
  if (previousFieldName && previousIndex && handBrake !== 'handBrakeFromCell') {
    if (position === 'left') {
      previousRow[previousFieldName] = previousRow[previousFieldName] || {};
      previousRow[previousFieldName].hasLeftIronShoe = false;
      previousRow[previousFieldName].leftIronShoeId = null;
      previousRow[previousFieldName].destination = '';
    } else if (position === 'right') {
      previousRow[previousFieldName] = previousRow[previousFieldName] || {};
      previousRow[previousFieldName].hasRightIronShoe = false;
      previousRow[previousFieldName].rightIronShoeId = null;
      previousRow[previousFieldName].destination = '';
    }
  }
  if (previousFieldName && previousIndex && handBrake === 'handBrakeFromCell') {
    previousRow[previousFieldName] = previousRow[previousFieldName] || {};
    previousRow[previousFieldName].hasHandBrake = false;
  }
  const id = event.dataTransfer?.getData('ironShoe');
  const item = ironShoeData.value.find((item) => item.id === Number(id));
  if (item) {
    item.alreadyUsed = 0;
    item.destination = '';
  }
};

const rootRef = ref<HTMLElement | null>(null);
const tooltipRef = ref<HTMLElement | null>(null);
// tooltip配置
const tooltipConfigs = reactive<{
  visible: boolean;
  position: { top: number; left: number };
  content: Record<string, any>;
}>({
  visible: false,
  position: { top: 0, left: 0 },
  content: {}
});
// tooltip显示内容配置
const tooltipDataConfig: {
  label: string;
  name: string;
  unit?: string;
}[] = [
  { label: '车皮号', name: 'carNumber' },
  { label: '进厂车次', name: 'inFactoryTrain' },
  { label: '品名', name: 'materialName' },
  { label: '停时', name: 'stopTime', unit: 'h' },
  { label: '车型', name: 'carType' },
  { label: '载重', name: 'load', unit: '吨' },
  { label: '自重', name: 'selfWeight', unit: '吨' },
  { label: '皮重', name: 'tare', unit: '吨' },
  { label: '列检结果', name: 'columnCheckResult' },
  { label: '货检结果', name: 'goodsCheckResult' },
  { label: '货物发站', name: 'goodsSendStation' },
  { label: '货物到站', name: 'goodsArriveStation' },
  { label: '厂外发站', name: 'outFactorySendStation' },
  { label: '收货单位', name: 'receivingCompany' },
  { label: '备注', name: 'remark' }
];
const mouseOverCell = (event: MouseEvent, row: Record<string, any>, fieldName: string) => {
  event.preventDefault();
  row[fieldName] = row[fieldName] || {};
  tooltipConfigs.content = row[fieldName];
  tooltipConfigs.visible = true;
  const cell = event.target as HTMLElement;
  const updateTooltipPosition = (event: MouseEvent) => {
    const { clientWidth: clientWidth, clientHeight: clientHeight } = rootRef.value!;
    const { clientWidth: tooltipWidth, clientHeight: tooltipHeight } = tooltipRef.value!;
    const offset = { top: 20, left: 200 };
    // 如果鼠标移动到接近页面右侧或者底部时，需要调整tooltip的位置
    event.clientX + tooltipWidth - 150 > clientWidth && (offset.left = tooltipWidth + 230);
    event.clientX < 200 && (offset.left = 20);
    event.clientY + tooltipHeight - 20 > clientHeight && (offset.top = tooltipHeight - 20);
    tooltipConfigs.position = {
      top: event.clientY - offset.top,
      left: event.clientX - offset.left
    };
  };
  cell.addEventListener('mousemove', updateTooltipPosition);

  // 在 mouseLeaveCell 中移除 mousemove 事件监听器
  const mouseLeaveHandler = () => {
    cell.removeEventListener('mousemove', updateTooltipPosition);
    mouseLeaveCell(event, row, fieldName);
  };
  cell.addEventListener('mouseleave', mouseLeaveHandler, { once: true });
};

const mouseLeaveCell = (event: MouseEvent, row: Record<string, any>, fieldName: string) => {
  event.preventDefault();
  row[fieldName] = row[fieldName] || {};
  tooltipConfigs.visible = false;
};

const statisticData = reactive<Record<string, number>>({
  totalWagon: 0,
  heavyWagon: 0,
  emptyWagon: 0
});

const getData = () => {};

const exportDialogVisible = ref<boolean>(false);
// 导出弹窗中的查询条件中，不包含时间范围选择器的值
const queryContentWithoutTime = ref<
  { label: string; name: string; value: unknown; type?: string }[]
>([]);
// 导出弹窗中的查询条件中，时间范围选择器值的集合
const queryContentTime = ref<{ label: string; name: string; value: unknown; type?: string }[]>([]);
// 用于导出接口的查询条件，由于在弹窗中可以继续编辑查询条件，因此需要设置该变量
const queryFormForExport = ref<Record<string, unknown>>({});
const openExportDialog = () => {
  // 复制queryForm的内容到queryFormForExport中
  queryFormForExport.value = _.cloneDeep(queryForm);
  // 清空之前的结果
  queryContentWithoutTime.value = [];
  queryContentTime.value = [];
  // 遍历queryFormConfig.value
  queryFormConfig.value.forEach((item) => {
    // 如果queryForm中对应的属性值为空或为空数组，则跳过这次迭代
    let fieldValue = queryForm[item.fieldName];
    if (!fieldValue || (Array.isArray(fieldValue) && fieldValue.length === 0)) {
      return;
    }
    // 如果属性值是下拉框，需要选择其中的label值
    if (item.fieldType === 'SELECT') {
      const fieldOptions = queryFormConfigInit.find(
        (i) => i.fieldName === item.fieldName
      )!.fieldOptions;
      fieldValue = fieldOptions?.find((i) => i.value === queryForm[item.fieldName])?.label;
    }
    // 如果属性值是数组，使用", "字符串将元素连接起来
    if (
      Array.isArray(fieldValue) &&
      !(item.fieldType === 'RANGE_DATE' || item.fieldType === 'RANGE_DATETIME')
    ) {
      fieldValue = fieldValue.join(', ');
    }
    // 生成要添加的对象
    const objToAdd = {
      label: item.fieldLabel,
      name: item.fieldName,
      value: fieldValue,
      type: item.fieldType
    };
    // 根据fieldType的值将数据分类到queryContentWithoutTime和queryContentTime
    if (item.fieldType === 'RANGE_DATE' || item.fieldType === 'RANGE_DATETIME') {
      queryContentTime.value.push(objToAdd);
    } else {
      queryContentWithoutTime.value.push(objToAdd);
    }
  });
  console.log(queryContentTime.value);
  exportDialogVisible.value = true;
};
const clearQueryWithoutTime = () => {
  queryFormConfigInit.forEach((item) => {
    if (item.fieldType === 'RANGE_DATE' || item.fieldType === 'RANGE_DATETIME') {
      return;
    }
    if (item.valueType === 'ARRAY') {
      queryFormForExport.value[item.fieldName] = [];
    } else if (!item.valueType || item.valueType === 'STRING') {
      queryFormForExport.value[item.fieldName] = '';
    } else if (item.value === 'NUMBER' || item.valueType === 'DATE') {
      queryFormForExport.value[item.fieldName] = null;
    } else {
      queryFormForExport.value[item.fieldName] = null;
    }
  });
  queryContentWithoutTime.value = [];
};
const deleteTimeItem = (fieldName: string) => {
  queryFormForExport.value[fieldName] = [];
  queryContentTime.value = queryContentTime.value.filter((item) => item.name !== fieldName);
};
const onExport = () => {
  // TODO: 导出逻辑，一般情况是向后端接口传查询条件
  console.log(queryFormForExport.value);
  // 在条件传输给后端之后，需要将导出弹窗关闭，并打开“数据处理中”弹窗
  exportDialogVisible.value = false;
  exportConfirmedDialogVisible.value = true;
  remainingSeconds.value = 10;
  startTimer();
};
const exportConfirmedDialogVisible = ref<boolean>(false);
// 跳转到导出页面
const moveToExportPage = () => {
  // TODO: 跳转到导出页面
  const exportPathName = '/';
  router.push({ path: exportPathName });
  return;
};
// “数据处理中”弹窗剩余描述
const remainingSeconds = ref<number>(10);
// 计时器
const exportDialogTimer = ref<number | null>(null);
const startTimer = () => {
  exportDialogTimer.value = setInterval(() => {
    if (remainingSeconds.value > 1) {
      remainingSeconds.value--;
    } else {
      exportConfirmedDialogVisible.value = false;
      clearTimer();
    }
  }, 1000);
};
const clearTimer = () => {
  if (exportDialogTimer.value) {
    clearInterval(exportDialogTimer.value);
    exportDialogTimer.value = null;
  }
};

const drawerVisible = ref<boolean>(false);
watch(drawerVisible, (newVal) => {
  if (newVal) {
    nextTick(() => {
      new Sortable(sortableDrawerQuery.value!, {
        animation: 150,
        onEnd: (evt: SortableEvent) => {
          if (evt.oldIndex === undefined || evt.newIndex === undefined) return;
          const itemMoved = queryFormConfigDrawer.value.splice(evt.oldIndex, 1)[0];
          queryFormConfigDrawer.value.splice(evt.newIndex, 0, itemMoved);
        }
      });
      new Sortable(sortableDrawerTable.value!, {
        animation: 150,
        onEnd: (evt: SortableEvent) => {
          if (evt.oldIndex === undefined || evt.newIndex === undefined) return;
          const itemMoved = tableColumnsConfigDrawer.value.splice(evt.oldIndex, 1)[0];
          tableColumnsConfigDrawer.value.splice(evt.newIndex, 0, itemMoved);
        }
      });
    });
  }
});

// 表格头部功能区配置
const isHovering = ref<string>('');
const isFullScreen = ref<boolean>(false);
const tableArea = ref<HTMLElement | null>(null);
const tableHeaderConfigs = reactive([
  {
    label: '刷新',
    icon: 'Refresh',
    click: () => {
      onQuery();
    }
  },
  {
    label: '导出',
    icon: 'Download',
    click: () => {
      openExportDialog();
    }
  },
  {
    label: '全屏',
    icon: 'FullScreen',
    click: () => {
      const element = tableArea.value;
      if (!isFullScreen.value) {
        isFullScreen.value = true;
        element?.classList.add('p-5', 'overflow-y-auto');
        element?.requestFullscreen();
      } else {
        document.exitFullscreen();
        if (element?.classList.contains('p-5')) {
          element?.classList.remove('p-5', 'overflow-y-auto');
        }
      }
    }
  },
  {
    label: '设置',
    icon: 'Setting',
    click: async () => {
      // 从indexedDB中获取页面配置项
      const config = (await localForage.getItem(localForageKey)) as PageConfig | null;
      const configOrderQuery = config?.queryFormOrder || {};
      const configFilterQuery = config?.queryFormFilter || {};
      const configOrderTable = config?.tableColumnsOrder || {};
      const configFilterTable = config?.tableColumnsFilter || {};
      // 将页面配置项赋值到抽屉组件的配置项中
      queryFormConfigInit
        .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
        .forEach((item) => {
          queryFormConfigDrawer.value[configOrderQuery[item.fieldName]] = item;
          queryFormConfigFilterDrawer.value[item.fieldName] = !!configFilterQuery[item.fieldName];
        });
      queryFormConfigDrawerFixedLeft.value = queryFormConfigInit.filter(
        (item) => item.fixMode === 'left'
      );
      queryFormConfigDrawerFixedRight.value = queryFormConfigInit.filter(
        (item) => item.fixMode === 'right'
      );

      tableColumnsConfigInit
        .filter((item) => item.fixMode !== 'left' && item.fixMode !== 'right')
        .forEach((item) => {
          tableColumnsConfigDrawer.value[configOrderTable[item.fieldName]] = item;
          tableColumnsConfigFilterDrawer.value[item.fieldName] =
            !!configFilterTable[item.fieldName];
        });
      tableColumnsConfigDrawerFixedLeft.value = tableColumnsConfigInit.filter(
        (item) => item.fixMode === 'left'
      );
      tableColumnsConfigDrawerFixedRight.value = tableColumnsConfigInit.filter(
        (item) => item.fixMode === 'right'
      );
      handleCheckedFieldChange();
      handleCheckedFieldChangeTable();
      drawerVisible.value = true;
    }
  }
]);

// 当执行exitFullscreen时，isFullScreen设为false
document.addEventListener('fullscreenchange', () => {
  const element = tableArea.value;
  if (!document.fullscreenElement) {
    isFullScreen.value = false;
    if (element?.classList.contains('p-5')) {
      element?.classList.remove('p-5');
    }
    if (element?.classList.contains('overflow-y-auto')) {
      element?.classList.remove('overflow-y-auto');
    }
  }
});

// 抽屉查询区选择和拖拽逻辑
const queryCheckAll = ref<boolean>(false);
const isIndeterminateQuery = ref<boolean>(false);
const handleCheckAllChangeQuery = (val: boolean) => {
  if (val) {
    Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
      queryFormConfigFilterDrawer.value[item] = true;
    });
  } else {
    Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
      queryFormConfigFilterDrawer.value[item] = false;
    });
  }
  isIndeterminateQuery.value = false;
};

// 抽屉列表区选择和拖拽逻辑
const tableCheckAll = ref<boolean>(false);
const isIndeterminateTable = ref<boolean>(false);
const handleCheckAllChangeTable = (val: boolean) => {
  if (val) {
    Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
      tableColumnsConfigFilterDrawer.value[item] = true;
    });
  } else {
    Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
      tableColumnsConfigFilterDrawer.value[item] = false;
    });
  }
  isIndeterminateTable.value = false;
};

const handleCheckedFieldChange = () => {
  let checkedCount = 0;
  Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
    queryFormConfigFilterDrawer.value[item] ? checkedCount++ : '';
  });
  const totalCount = Object.keys(queryFormConfigFilterDrawer.value).length;
  queryCheckAll.value = checkedCount === totalCount;
  isIndeterminateQuery.value = checkedCount > 0 && checkedCount < totalCount;
};
const changeOrderQuery = (index: number, type: 'up' | 'down') => {
  if (type === 'up') {
    if (index === 0) return;
    const temp = queryFormConfigDrawer.value[index];
    queryFormConfigDrawer.value[index] = queryFormConfigDrawer.value[index - 1];
    queryFormConfigDrawer.value[index - 1] = temp;
  } else {
    if (index === queryFormConfigDrawer.value.length - 1) return;
    const temp = queryFormConfigDrawer.value[index];
    queryFormConfigDrawer.value[index] = queryFormConfigDrawer.value[index + 1];
    queryFormConfigDrawer.value[index + 1] = temp;
  }
};

const handleCheckedFieldChangeTable = () => {
  let checkedCount = 0;
  Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
    tableColumnsConfigFilterDrawer.value[item] ? checkedCount++ : '';
  });
  const totalCount = Object.keys(tableColumnsConfigFilterDrawer.value).length;
  tableCheckAll.value = checkedCount === totalCount;
  isIndeterminateTable.value = checkedCount > 0 && checkedCount < totalCount;
};
const changeOrderTable = (index: number, type: 'up' | 'down') => {
  if (type === 'up') {
    if (index === 0) return;
    const temp = tableColumnsConfigDrawer.value[index];
    tableColumnsConfigDrawer.value[index] = tableColumnsConfigDrawer.value[index - 1];
    tableColumnsConfigDrawer.value[index - 1] = temp;
  } else {
    if (index === tableColumnsConfigDrawer.value.length - 1) return;
    const temp = tableColumnsConfigDrawer.value[index];
    tableColumnsConfigDrawer.value[index] = tableColumnsConfigDrawer.value[index + 1];
    tableColumnsConfigDrawer.value[index + 1] = temp;
  }
};

// 对右侧抽屉的引用
const rightDrawer = ref<InstanceType<typeof ElDrawer>>();
// 关闭右侧抽屉
const handleDrawerClose = () => {
  drawerAreaType.value = '查询区';
  rightDrawer.value?.handleClose();
};
// 保存右侧抽屉的配置项
const saveDrawerData = async () => {
  const CurdStandardPage = ((await localForage.getItem(localForageKey)) as PageConfig) || {};
  let fieldOrder: Record<string, number> = {};
  let fieldFilter: Record<string, number> = {};
  let fieldOrderTable: Record<string, number> = {};
  let fieldFilterTable: Record<string, number> = {};

  queryFormConfigDrawer.value.forEach((item, index) => {
    fieldOrder[item.fieldName] = index;
  });
  Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
    fieldFilter[item] = queryFormConfigFilterDrawer.value[item] ? 1 : 0;
  });
  tableColumnsConfigDrawer.value.forEach((item, index) => {
    fieldOrderTable[item.fieldName] = index;
  });
  Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
    fieldFilterTable[item] = tableColumnsConfigFilterDrawer.value[item] ? 1 : 0;
  });

  CurdStandardPage.queryFormOrder = fieldOrder;
  CurdStandardPage.queryFormFilter = fieldFilter;
  CurdStandardPage.tableColumnsOrder = fieldOrderTable;
  CurdStandardPage.tableColumnsFilter = fieldFilterTable;

  await localForage.setItem(localForageKey, CurdStandardPage);
  handleDrawerClose();
  reloadPage();
};

// 右侧抽屉弹窗配置项
const drawerAreaType = ref<string>('查询区');
</script>

<style lang="scss" scoped>
:deep(.table-custom) {
  .index-column.el-table__cell {
    .cell {
      padding-left: 10px;
    }
  }
  .header-cell-custom.el-table__cell {
    .cell {
      padding-left: 10px;
    }
  }
  .el-table__cell {
    padding: 0;
    .cell {
      display: flex;
      align-items: center;
      padding: 0;
      width: 100%;
      height: 100%;
    }
  }
}

.export-dialog-custom::-webkit-scrollbar {
  width: 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.1);
}
.export-dialog-custom::-webkit-scrollbar-thumb {
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.2);
}
:global(.icon-hover .el-icon) {
  color: #697dff;
}
:global(.el-drawer__header) {
  border-bottom: 1px solid #ddd;
  color: #222;
  margin: 0;
  padding: 20px;
}
:global(.limited-picker .el-date-range-picker__time-picker-wrap:nth-child(1) .el-input__wrapper) {
  background: #f5f7fa;
  cursor: not-allowed;
}
:global(.limited-picker .el-date-range-picker__time-picker-wrap:nth-child(1) input) {
  color: #a8abb2;
  cursor: not-allowed;
}
:global(.el-dialog-custom .el-dialog) {
  border-radius: 8px;
  box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.3);
}
:global(.el-dialog-custom .el-dialog .el-dialog__header) {
  background: #f2f2f2;
  margin: 0;
  padding: 16px 20px;
  border-radius: 8px 8px 0 0;
}
:global(.el-dialog-custom .el-dialog .el-dialog__footer) {
  padding: 12px 20px;
}
:global(.el-dialog-export-confirm-custom .el-dialog) {
  border-radius: 8px;
  box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.3);
}
</style>
